package com.jushu.storbox.actions;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.jushu.storbox.R;
import com.jushu.storbox.ShareDriveApplication;
import com.jushu.storbox.constant.ClientConfig;
import com.jushu.storbox.constant.Constant;
import com.jushu.storbox.constant.MessageCode;
import com.jushu.storbox.constant.UiConstant;
import com.jushu.storbox.database.DAOFactory;
import com.jushu.storbox.database.IFileDao;
import com.jushu.storbox.database.IFolderDao;
import com.jushu.storbox.entities.FileFolderInfo;
import com.jushu.storbox.entities.FileInfo;
import com.jushu.storbox.entities.FolderInfo;
import com.jushu.storbox.handler.ClientExceptionRelateHandler;
import com.jushu.storbox.service.ILocalFileService;
import com.jushu.storbox.service.IlocalFolderService;
import com.jushu.storbox.service.ServiceFactory;
import com.jushu.storbox.util.DirectoryUtil;
import com.jushu.storbox.util.LogUtil;
import com.jushu.storbox.view.dialog.ClouddriveDialog;
import com.jushu.storbox.vo.PagedList;
import com.huawei.sharedrive.sdk.android.exception.ClientException;
import com.huawei.sharedrive.sdk.android.model.request.FolderCreateRequest;
import com.huawei.sharedrive.sdk.android.modelV2.request.FolderListRequestV2;
import com.huawei.sharedrive.sdk.android.modelV2.request.FolderMoveRequstV2;
import com.huawei.sharedrive.sdk.android.modelV2.request.Order;
import com.huawei.sharedrive.sdk.android.modelV2.response.FileInfoResponseV2;
import com.huawei.sharedrive.sdk.android.modelV2.response.FolderListResponseV2;
import com.huawei.sharedrive.sdk.android.modelV2.response.FolderResponse;
import com.huawei.sharedrive.sdk.android.service.handler.AsyncTaskHandler;
import com.huawei.sharedrive.sdk.android.serviceV2.FolderClientV2;

public class FolderAction extends BaseAction {
	
	private final static String TAG = FolderAction.class.getName();
	
	public void openFolder(final Context context, final int messageCode, 
			final String ownerId, final String folderId,final String folderName, 
			final int pageNo, final Handler messageHandler) {
		executeRunTask(new RealTaskRunnable(context, messageHandler) {
			@Override
			protected void doTask(Context context, Handler msgHandler) throws ClientException {
				//init request
				List<Order> olist = new ArrayList<Order>();
		        olist.add(new Order("type","ASC"));
				FolderListRequestV2 request = new FolderListRequestV2();
		        request.setFolderID(folderId);
		        request.setLimit(ClientConfig.CLOUD_COUNT_PER_PAGE);
		        request.setOffset(pageNo * ClientConfig.CLOUD_COUNT_PER_PAGE);
		        request.setOwnerID(ownerId);
		        request.setOrder(olist);
		        
		        //send request for data
		        final FolderListResponseV2 response = FolderClientV2.getInstance().getFolderInfoList(request,
		            ShareDriveApplication.getInstance().getAuthorization());
		        
		        //procese result data
		        PagedList<FileFolderInfo> pagedList = new PagedList<FileFolderInfo>();
		        //fentch data and set some params of data
		        fentchDataToPagedList(context, response, pagedList);
				//set other params
				pagedList.setPageNumber(pageNo);
				pagedList.setOwnerId(ownerId);
				pagedList.setPagedFolderId(folderId);
				pagedList.setPagedFolderName(folderName);
				
				//return data to caller
				Message resourceMsg = new Message();
				resourceMsg.what = messageCode;
				resourceMsg.obj = pagedList;
				messageHandler.sendMessage(resourceMsg);
			}

			@Override
			protected void onNetworkUnAvailable(Context context,
					Handler msgHandler) {
				super.onNetworkUnAvailable(context, msgHandler);
				List<FileFolderInfo> pageList = new ArrayList<FileFolderInfo>();
				
				IlocalFolderService folderService = ServiceFactory.instance(context).getLocalFolderService();
				List<FolderInfo> folderList = folderService.getFolderList(ownerId, folderId);
				if(folderList != null) {
					pageList.addAll(folderList);
				}
				ILocalFileService fileService = ServiceFactory.instance(context).getLocalFileService();
				List<FileInfo> fileList = fileService.getFileList(ownerId, folderId);
				if(fileList != null) {
					pageList.addAll(fileList);
				}
				
				//procese result data
		        PagedList<FileFolderInfo> pagedList = new PagedList<FileFolderInfo>();
		        pagedList.setPagedList(pageList);
		        pagedList.setTotal(pageList.size());
		        
				//set other params
				pagedList.setPageNumber(pageNo);
				pagedList.setOwnerId(ownerId);
				pagedList.setPagedFolderId(folderId);
				pagedList.setPagedFolderName(folderName);
				
				//return data to caller
				Message resourceMsg = new Message();
				resourceMsg.what = messageCode;
				resourceMsg.obj = pagedList;
				messageHandler.sendMessage(resourceMsg);
			}
			
		});

	}
	
	public void createFolder(final String ownerId, final FolderCreateRequest request,
			final Context context, final Handler messageHandler) {
		LogUtil.i(TAG, "createFolder[Actions]");
		executeRunTask(new RealTaskRunnable(context, messageHandler) {
			@Override
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {
				FolderResponse folderResponse = FolderClientV2
						.getInstance().create(ownerId, request,
								getAuthCode());
				FileFolderInfo result = DAOFactory.instance(context)
						.getFolderDao().insertFolder(folderResponse, 0);
				Message msg = new Message();
				msg.obj = result;
				msg.what = MessageCode.CREATE_FOLDER_SUCCESS;
				messageHandler.sendMessage(msg);
			}
		});
	}
	
	public void renameFolder(final String folderName,final FileFolderInfo fileInformation,
			final Context context, final Handler messageHandler) {
		LogUtil.i(TAG, "renameFolder[Actions]");
		executeRunTask(new RealTaskRunnable(context, messageHandler) {
			@Override
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {
				FolderResponse folderResponse = ServiceFactory.getRemoteFolderService().renameFolder(fileInformation, folderName);
		        FileFolderInfo response = ServiceFactory.instance(context).getLocalFolderService().renameFolder(
		            folderResponse,
		            fileInformation);
		        fileInformation.setName(folderName);
				Message msg = new Message();
				msg.obj = fileInformation;
				msg.what = MessageCode.RENAME_SUCCESS;
				messageHandler.sendMessage(msg);
			}
		});
	}
	
	public void deleteFolder(final Context context,
			final FileFolderInfo fileInformation, final Handler messageHandler) {
		LogUtil.i(TAG, "deleteAllFile[Actions]");
		final AsyncTaskHandler deleteCallback = new AsyncTaskHandler(){
			@Override
			public void onExecuting() {
			}
			@Override
			public void onSuccess() {
				DirectoryUtil.deleteFileThumbnailPath(context, fileInformation.getOwnerBy(),
						fileInformation.getId(), fileInformation.getName());
				ServiceFactory.instance(context).getLocalFileService().deleteFile(fileInformation);
				DirectoryUtil.deleteFile(context, fileInformation);
				
				Message resourceMsg = new Message();
				resourceMsg.what = MessageCode.DELETE_FILE_SUCCESS;
				resourceMsg.obj = fileInformation;
				messageHandler.sendMessage(resourceMsg);
			}
			
			@Override
			public void onFailure(ClientException exception) {
				handleException(exception,messageHandler);
			}
		};
		executeRunTask(new RealTaskRunnable(context, messageHandler) {
			@Override
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {
				ServiceFactory.getRemoteFileService().deleteFileAsync(
						fileInformation, deleteCallback);
			}
		});
	}

	public void getNodeInfomationFromServer(final Context context, final String ownerId, final String nodeId, 
			final Handler messageHandler) {
		executeRunTask(new RealTaskRunnable(context, messageHandler) {
			@Override
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {
				
				FolderResponse response = ServiceFactory.getRemoteFolderService().getFolderResponse(ownerId , nodeId);
				FolderInfo info = new FolderInfo();
//				info.valueOf(response);
				info.setName(response.getName());
				info.setId(nodeId);
				info.setOwnerId(ownerId);
				Message msg = new Message();
				msg.obj = info;
				msg.what = UiConstant.FILE_ACTION_GET_NODE_INFOMATION;
				messageHandler.sendMessage(msg);
			}
		});
	}

	public void getSubFolderList(final Context context, final int messageCode,
			final String ownerId, final String folderId, final int pageNo, 
			final Handler messageHandler) {
		executeRunTask(new RealTaskRunnable(context, messageHandler) {
			@Override
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {
				String folderName;
				//init request order
		        List<Order> olist = new ArrayList<Order>();
		        olist.add(new Order("type", "ASC"));
		        //init request
				FolderListRequestV2 request = new FolderListRequestV2();
		        request.setFolderID(folderId);
		        request.setLimit(ClientConfig.CLOUD_COUNT_PER_PAGE);
		        request.setOffset(pageNo * ClientConfig.CLOUD_COUNT_PER_PAGE);
		        request.setOwnerID(ownerId);
		        request.setOrder(olist);
		        //request data from server
		        FolderListResponseV2 response = FolderClientV2.getInstance().getFolderInfoList(request,
		            ShareDriveApplication.getInstance().getAuthorization());
		        //request folder Name
		        if(folderId.equals("0")) {
//		        	folderName = context.getResources().getString(R.string.my_cloud_drive);
					folderName = null;
		        } else {
		        	FolderResponse folder = ServiceFactory.getRemoteFolderService().getFolderResponse(ownerId, folderId);
		        	folderName = folder.getName();
		        }
		        //fill server data to pageList
		        PagedList<FileFolderInfo> pagedList = new PagedList<FileFolderInfo>();
		        List<FileFolderInfo> fileFolderInfoList = new ArrayList<FileFolderInfo>();
		        List<FolderResponse> serverFolderList = response.getFolders();
		        if (null != response && null != serverFolderList) {
	            	for(FolderResponse item : serverFolderList) {
	            		FolderInfo tmpFolder = new FolderInfo();
	            		tmpFolder.valueOf(item);
	            		fileFolderInfoList.add(tmpFolder);
	            	}
		        }
		        pagedList.setPagedFolderId(folderId);
		        pagedList.setTotal(fileFolderInfoList.size());
	            pagedList.setPagedList(fileFolderInfoList);
	            pagedList.setPageNumber(pageNo);
	            pagedList.setPagedFolderName(folderName);
	            //return page data to the client
            	Message msg = messageHandler.obtainMessage();
            	msg.what = messageCode;
            	msg.obj = pagedList;
            	msg.sendToTarget();
				//do other things
			}
		});
	}

	public void getMoreNodeListFromServer(final Context context, final String ownerId,
			final String folderId,final int pageNo, final Handler messageHandler) {
		LogUtil.i(TAG, "getNodeListFromServer[Actions]");
		executeRunTask(new RealTaskRunnable(context, messageHandler) {
			protected void doTask(Context context, Handler msgHandler) throws ClientException {
				List<Order> olist = new ArrayList<Order>();
		        olist.add(new Order("type","ASC"));
				FolderListRequestV2 request = new FolderListRequestV2();
		        request.setFolderID(folderId);
		        request.setLimit(ClientConfig.CLOUD_COUNT_PER_PAGE);
		        request.setOffset(pageNo * ClientConfig.CLOUD_COUNT_PER_PAGE);
		        request.setOwnerID(ownerId);
		        request.setOrder(olist);
		        
		        final FolderListResponseV2 response = FolderClientV2.getInstance().getFolderInfoList(request,
		            ShareDriveApplication.getInstance().getAuthorization());
		        
		        //procese result data
		        PagedList<FileFolderInfo> pagedList = new PagedList<FileFolderInfo>();
				//fentch data and set some params of data
		        fentchDataToPagedList(context, response, pagedList);
				//set other params
		        pagedList.setPageNumber(pageNo);
				pagedList.setPagedFolderId(folderId);
				pagedList.setPagedFolderName("");
				
				//return data to caller
		        Message resourceMsg = new Message();
				resourceMsg.what = MessageCode.LOAD_FILE_LIST;
				resourceMsg.obj = pagedList;
				messageHandler.sendMessage(resourceMsg);

				LogUtil.i(TAG, "getAllFileListFromServer success[Actions]");
			}

			@Override
			protected void onNetworkUnAvailable(Context context,
					Handler msgHandler) {
				super.onNetworkUnAvailable(context, msgHandler);
				
				List<FileFolderInfo> pageList = new ArrayList<FileFolderInfo>();
				
				IlocalFolderService folderService = ServiceFactory.instance(context).getLocalFolderService();
				String folderName = "";
		        FolderInfo folder = folderService.getFolderById(ownerId, folderId);
		        if(folder != null ) {
		        	folderName = folder.getName();
		        }
				//procese result data
		        PagedList<FileFolderInfo> pagedList = new PagedList<FileFolderInfo>();
		        pagedList.setPagedList(pageList);
		        pagedList.setTotal(pageList.size());
		        
				//set other params
				pagedList.setPageNumber(pageNo);
				pagedList.setOwnerId(ownerId);
				pagedList.setPagedFolderId(folderId);
				pagedList.setPagedFolderName(folderName);
				
				//return data to caller
		        Message resourceMsg = new Message();
				resourceMsg.what = MessageCode.LOAD_FILE_LIST;
				resourceMsg.obj = pagedList;
				messageHandler.sendMessage(resourceMsg);
			}
			
			
		});
	}

	private void fentchDataToPagedList(Context context, FolderListResponseV2 fromResp, PagedList<FileFolderInfo> toPagedList) {
		List<FolderResponse> remoteFolderDatas = fromResp.getFolders();
		List<FileFolderInfo> dataList = new ArrayList<FileFolderInfo>();
		
		IFolderDao folderDao = DAOFactory.instance(context).getFolderDao();
		if(remoteFolderDatas !=null) {
			for(int i=0; i<remoteFolderDatas.size(); i++) {
				FolderResponse serverFolder = remoteFolderDatas.get(i);
				FolderInfo localFolder = folderDao.getFolderById(serverFolder);
				
				FolderInfo node = null;
				if(localFolder != null) {
					node = localFolder;
					node.copyFiledValue(serverFolder);
					folderDao.updateFolder(node);
				} else {
					node = new FolderInfo();
					node.valueOf(serverFolder);
					node.setSync(false);
					node.setTransStatus(Constant.DOWNLOAD_NON_UPDATE_DB);
					folderDao.insertFolder(node);
				}
				
				dataList.add(node);
			}
		}
		
		IFileDao fileDao = DAOFactory.instance(context).getFileDao();
		List<FileInfoResponseV2> remoteFileDatas = fromResp.getFiles();
		if(remoteFileDatas !=null) {
			for(int i=0; i<remoteFileDatas.size(); i++) {
				FileInfoResponseV2 serverFile = remoteFileDatas.get(i);
				FileInfo localfile = fileDao.getFile(serverFile);
				
				FileInfo node = null;
				serverFile = remoteFileDatas.get(i);
				if(localfile != null) {
					node = localfile;
					String filePath = DirectoryUtil.generateFileDownloadPath(context, localfile.getOwnerBy(), localfile.getId(), localfile.getName());
					File realFile = new File(filePath);
					if(!realFile.exists()) {
						localfile.setTransStatus(Constant.DOWNLOAD_NON_UPDATE_DB);
						fileDao.updateTransStatus(localfile, Constant.DOWNLOAD_NON_UPDATE_DB);
					}
					node.copyFiledValue(serverFile);
					fileDao.update(node);
				} else {
					node = new FileInfo();
					node.valueOf(remoteFileDatas.get(i));
					node.setLocalIdentity(node.getIdentity());
					node.setSync(false);
					node.setTransStatus(Constant.DOWNLOAD_NON_UPDATE_DB);
					fileDao.insertFile(node);
				}
				dataList.add(node);
			}
		}
		toPagedList.setPagedList(dataList);
		toPagedList.setTotal(dataList.size());
	}
	
	public void moveFolder(final Context context,final int messageCode,
			final FileFolderInfo sourceNode, 
			final String targetFolderId, final String targetFolderOwnerId, 
			final Handler messageHandler) {
		executeRunTask(new RealTaskRunnable(context, messageHandler) {
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {FolderMoveRequstV2 request = new FolderMoveRequstV2();
					request.setDestParent(targetFolderId);
					request.setAutoRename(false);
					request.setDestOwnerId(targetFolderOwnerId);
			        FolderClientV2.getInstance().moveFolder(sourceNode.getOwnerId(), sourceNode.getId(), getAuthCode(), request);
			        
			        Message msg = messageHandler.obtainMessage();
			        msg.what = messageCode;
			        msg.obj = sourceNode;
			        msg.sendToTarget();
			        }

			@Override
			protected boolean filterException(ClientException e, final Handler handler) {
				if(e.getStatusCode() == ClientExceptionRelateHandler.ERROR_CODE_409_SOURCE_CONFLICT
						&& ClientExceptionRelateHandler.RepeatNameConflict.equals(e.getCode())) {
		            handler.post(new Runnable(){
						@Override
						public void run() {
							final ClouddriveDialog move = new ClouddriveDialog(context, R.style.dialog_upload,
					                R.layout.dialog_filedelete);
				            View conventView = move.getConventView();
				            Button dialog_cancal = (Button) conventView.findViewById(R.id.dialog_add_file_cancal_bt);
				            Button dialog_OK = (Button) conventView.findViewById(R.id.dialog_add_file_ok_bt);
				            TextView dialog_prompt_tv = (TextView) conventView.findViewById(R.id.dialog_prompt_tv);
				            dialog_prompt_tv.setText(context.getString(R.string.allfile_confirm_reanme_filefolder));
				            dialog_cancal.setOnClickListener(new View.OnClickListener() {
				                @Override
				                public void onClick(View v) {
				                	move.dismiss();//单个文件夹移动取消自动重命名
				                	handler.sendEmptyMessage(UiConstant.NODE_ACTION_MOVE_CANCEL);
				                }
				            });
				            dialog_OK.setOnClickListener(new View.OnClickListener() {
				                @Override
				                public void onClick(View v) {
				                	move.dismiss();
				                	moveFolderWithAutoRename(context, messageCode, sourceNode, targetFolderId, targetFolderOwnerId, handler);
				                }
				            });
				            move.show();
						}
		            });
					return true;
				} else {
					return false;
				}
			}
		});
	}

	public void moveFolderWithAutoRename(final Context context,final int messageCode,
			final FileFolderInfo sourceNode, 
			final String targetFolderId, final String targetFolderOwnerId, 
			final Handler messageHandler){
		executeRunTask(new RealTaskRunnable(context, messageHandler) {
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {
				FolderMoveRequstV2 request = new FolderMoveRequstV2();
				request.setDestParent(targetFolderId);
				request.setAutoRename(true);
				request.setDestOwnerId(targetFolderOwnerId);
		        FolderClientV2.getInstance().moveFolder(sourceNode.getOwnerId(), sourceNode.getId(), getAuthCode(), request);
		        
		        Message msg = messageHandler.obtainMessage();
		        msg.what = messageCode;
		        msg.obj = sourceNode;
		        msg.sendToTarget();
			}
		});
	}
}
